﻿#pragma warning disable 1591,0618,0105,0672

using System;
using System.Reactive;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using ReactiveUI.Events;

{{#Namespaces}}
using {{Name}};
{{/Namespaces}}
{{#DelegateNamespaces}}
using {{Name}};
{{/DelegateNamespaces}}

{{#Namespaces}}
namespace {{Name}}
{
    public static class EventsMixin
    {
{{#Types}}
        public static {{Name}}Events Events(this {{Name}} This)
        {
            return new {{Name}}Events(This);
        }
{{/Types}}
    }

{{#Types}}
    public class {{Name}}Events
{{#Parent}}
        : {{Name}}Events
{{/Parent}}
    {
        {{Name}} This;

        public {{Name}}Events({{Name}} This)
{{#Parent}}
            : base(This)
{{/Parent}}
        {
            this.This = This;
        }

{{#Events}}
        public IObservable<{{EventArgsType}}> {{Name}} {
            get { return Observable.FromEventPattern<{{EventHandlerType}}, {{EventArgsType}}>(x => This.{{Name}} += x, x => This.{{Name}} -= x).Select(x => x.EventArgs); }
        }

{{/Events}}
    }
{{/Types}}
}
{{/Namespaces}}

{{#DelegateNamespaces}}
namespace {{Name}}.Rx
{
{{#Types}}
    public {{Abstract}} partial class {{Name}}Rx : {{Name}}
    {
{{#ZeroParameterMethods}}
        readonly SingleAwaitSubject<Unit> _{{Name}} = new SingleAwaitSubject<Unit>();
        public IObservable<Unit> {{Name}}Obs { get { return _{{Name}}; } }
        public override void {{Name}}()
        {
            _{{Name}}.OnNext(Unit.Default);
        }

{{/ZeroParameterMethods}}
{{#SingleParameterMethods}}
        readonly SingleAwaitSubject<{{ParameterType}}> _{{Name}} = new SingleAwaitSubject<{{ParameterType}}>();
        public IObservable<{{ParameterType}}> {{Name}}Obs { get { return _{{Name}}; } }
        public override void {{Name}}({{ParameterType}} {{ParameterName}})
        {
            _{{Name}}.OnNext({{ParameterName}});
        }

{{/SingleParameterMethods}}
{{#MultiParameterMethods}}
        readonly SingleAwaitSubject<Tuple<{{ParameterTypeList}}>> _{{Name}} = new SingleAwaitSubject<Tuple<{{ParameterTypeList}}>>();
        public IObservable<Tuple<{{ParameterTypeList}}>> {{Name}}Obs { get { return _{{Name}}; } }
        public override void {{Name}}({{ParameterList}})
        {
            _{{Name}}.OnNext(Tuple.Create({{ParameterNameList}}));
        }

{{/MultiParameterMethods}}
    }
{{/Types}}
}
{{/DelegateNamespaces}}

#pragma warning restore 1591,0618,0105,0672